package com.wei.czz.framework.blog.manager;

import com.wei.czz.common.dto.admin.AdminDto;
import com.wei.czz.common.dto.echarts.LineEchartsDto;
import com.wei.czz.common.enums.ResultEnum;
import com.wei.czz.common.enums.blog.BlogStatsFlowEnum;
import com.wei.czz.common.exception.CzzException;
import com.wei.czz.common.utils.TimeUtils;
import com.wei.czz.common.vo.admin.AdminVo;
import com.wei.czz.framework.blog.entity.BlogIssueEntity;
import com.wei.czz.framework.blog.entity.BlogStatsFlowEntity;
import com.wei.czz.framework.blog.service.BlogIssueService;
import com.wei.czz.framework.blog.service.BlogService;
import com.wei.czz.framework.blog.service.BlogStatsFlowService;
import com.wei.czz.framework.blog.service.BlogStatsService;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wyw
 * date: 2023-12-11 20:41:48
 * className: BlogStatsManager
 * version: 1.0
 * description:
 */
@Component
@AllArgsConstructor
public class BlogStatsManager {

    private static final Logger log = LoggerFactory.getLogger(BlogStatsManager.class);

    private final BlogStatsService blogStatsService;

    private final BlogStatsFlowService blogStatsFlowService;

    private final BlogIssueService blogIssueService;

    private final BlogService blogService;

    public AdminDto getUserBlogStats(Long userId, AdminVo adminVo, BlogStatsFlowEnum userBlogStats,
                                     BlogStatsFlowEnum valueType) {
        AdminDto adminDto = new AdminDto();

        int[] array = new int[4];
        for (String num : adminVo.getRefresh().split(",")) {
            array[Integer.parseInt(num)]++;
        }

        Date nowDate = new Date();

        Date startDate;
        if (valueType == BlogStatsFlowEnum.DAY_VALUE) {
            throw new CzzException(ResultEnum.REQUEST_FAIL.getCode(), "当前不支持查询日统计数据");
        } else if (valueType == BlogStatsFlowEnum.MONTH_VALUE) {
            startDate = TimeUtils.firstDayOnThisMonth();
        } else {
            startDate = TimeUtils.firstDayOnThisYear();
        }

        if (array[0] == 1) {
            // 获取用户已发布的博客数量
            Long issueBlogNum = blogIssueService.getUserIssueBlogNum(userId, startDate, nowDate);
            adminDto.setIssueBlogNum(issueBlogNum);
        }
        if (array[1] == 1) {
            // 获取用户已发布博客的总浏览数量
            Long blogViewNum = blogStatsService.getUserBlogStats(userId, BlogStatsFlowEnum.BLOG_VIEW_STATS.getValue(),
                    adminVo.getValueType());
            adminDto.setBlogViewNum(blogViewNum);
        }
        if (array[2] == 1) {
            // 获取用户已发布博客的总点赞数量
            Long blogLikeNum = blogStatsService.getUserBlogStats(userId, BlogStatsFlowEnum.BLOG_LIKE_STATS.getValue(),
                    adminVo.getValueType());
            adminDto.setBlogLikeNum(blogLikeNum);
        }
        if (array[3] == 1) {
            // 获取用户已发布博客的总评论数量
            Long blogCommentNum = blogStatsService.getUserBlogStats(userId,
                    BlogStatsFlowEnum.BLOG_COMMENT_STATS.getValue(), adminVo.getValueType());
            adminDto.setBlogCommentNum(blogCommentNum);
        }

        return adminDto;
    }

    public LineEchartsDto getUserBlogStats(Long userId, BlogStatsFlowEnum userBlogStats, BlogStatsFlowEnum valueType) {
        Date nowDate = new Date();
        DateFormat dateFormat;

        Date startDate;
        if (valueType == BlogStatsFlowEnum.DAY_VALUE) {
            throw new CzzException(ResultEnum.REQUEST_FAIL.getCode(), "当前不支持查询日统计数据");
        } else if (valueType == BlogStatsFlowEnum.MONTH_VALUE) {
            startDate = TimeUtils.firstDayOnThisMonth();

            dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        } else {
            startDate = TimeUtils.firstDayOnThisYear();

            dateFormat = new SimpleDateFormat("yyyy-MM");
        }

        LineEchartsDto lineEchartsDto = new LineEchartsDto();

        if (userBlogStats == BlogStatsFlowEnum.ISSUE_BLOG_STATS) {
            /*
                范围查询用户已发布博客列表
             */
            List<BlogIssueEntity> blogIssueEntityList = blogIssueService.getUserIssueBlogList(userId, startDate,
                    nowDate);

            Map<String, Integer> map = new HashMap<>();
            // 分组
            for (BlogIssueEntity blogIssue : blogIssueEntityList) {
                Date issueTime = blogIssue.getIssueTime();
                String date = dateFormat.format(issueTime);

                Integer num = map.getOrDefault(date, 0);

                map.put(date, num + 1);
            }
            List<String> dates = new ArrayList<>(map.size());
            List<Integer> values = new ArrayList<>(map.size());
            for (Map.Entry<String, Integer> entry : map.entrySet()) {
                dates.add(entry.getKey());
                values.add(entry.getValue());
            }

            lineEchartsDto.setXAxisData(dates);
            lineEchartsDto.setSeriesData(values);

        } else {
            /*
                userBlogStats == BlogStatsFlowDict.BLOG_VIEW_STATS:     用户已发布博客的总浏览数量走势数据
                userBlogStats == BlogStatsFlowDict.BLOG_LIKE_STATS:     用户已发布博客的总点赞数量走势数据
                userBlogStats == BlogStatsFlowDict.BLOG_COMMENT_STATS:  用户已发布博客的总评论数量走势数据
             */
            // 查询当日/月的统计数据
            Long num = blogStatsService.getUserBlogStats(userId, userBlogStats.getValue(),
                    valueType.getValue() - 1);

            // 查询以往的统计数据
            List<BlogStatsFlowEntity> blogStatsFlowList = blogStatsFlowService.getUserBlogStats(userId,
                    userBlogStats.getValue(), valueType.getValue() - 1, startDate, nowDate);

            Map<String, Integer> map = new HashMap<>();
            // 分组
            for (BlogStatsFlowEntity blogStatsFlow : blogStatsFlowList) {
                String date = dateFormat.format(blogStatsFlow.getStartTime());

                Integer value = map.getOrDefault(date, 0);

                map.put(date, value + 1);
            }
            List<String> dates = new ArrayList<>(map.size());
            List<Integer> values = new ArrayList<>(map.size());
            for (Map.Entry<String, Integer> entry : map.entrySet()) {
                dates.add(entry.getKey());
                values.add(entry.getValue());
            }
            if (num != null) {
                dates.add(dateFormat.format(nowDate));
                values.add(num.intValue());
            }


            lineEchartsDto.setXAxisData(dates);
            lineEchartsDto.setSeriesData(values);
        }

        return lineEchartsDto;
    }
}
